home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / m88k-xdep.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  9KB  |  334 lines

  1. /* Copyright (C) 1988, 1990 Free Software Foundation, Inc.
  2.  
  3. This file is part of GDB.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <stdio.h>
  20. #include "defs.h"
  21. #include "param.h"
  22. #include "frame.h"
  23. #include "inferior.h"
  24.  
  25. #ifdef USG
  26. #include <sys/types.h>
  27. #endif
  28.  
  29. #include <sys/param.h>
  30. #include <sys/dir.h>
  31. #include <signal.h>
  32. #include "gdbcore.h"
  33. #include <sys/user.h>
  34. #ifndef USER            /* added to support BCS ptrace_user */
  35.  
  36. #define USER ptrace_user
  37. #endif
  38. #include <sys/ioctl.h>
  39. #include <fcntl.h>
  40. #include <sys/file.h>
  41. #include <sys/stat.h>
  42.  
  43. #include "symtab.h"
  44. #include "setjmp.h"
  45. #include "value.h"
  46.  
  47. /* define offsets to the pc instruction offsets in ptrace_user struct */
  48. #define SXIP_OFFSET (char *)&u.pt_sigframe.dg_sigframe.sc_sxip - \
  49.                 (char *)&u
  50.  
  51. #define SNIP_OFFSET (char *)&u.pt_sigframe.dg_sigframe.sc_snip - \
  52.                 (char *)&u
  53.  
  54. #define SFIP_OFFSET (char *)&u.pt_sigframe.dg_sigframe.sc_sfip - (char *)&u
  55. extern int have_symbol_file_p();
  56.  
  57. extern jmp_buf stack_jmp;
  58.  
  59. extern int errno;
  60. extern char registers[REGISTER_BYTES];
  61.  
  62. void
  63. fetch_inferior_registers ()
  64. {
  65.   register int regno;
  66.   register unsigned int regaddr;
  67.   char buf[MAX_REGISTER_RAW_SIZE];
  68.   register int i;
  69.  
  70.   struct USER u;
  71.   unsigned int offset;
  72.  
  73.   offset = (char *) &u.pt_r0 - (char *) &u; 
  74.   regaddr = offset; /* byte offset to r0;*/
  75.  
  76. /*  offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; */
  77.   for (regno = 0; regno < NUM_REGS; regno++)
  78.     {
  79.       /*regaddr = register_addr (regno, offset);*/
  80.     /* 88k enhancement  */
  81.         
  82.       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
  83.      {
  84.        *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0);
  85.        regaddr += sizeof (int);
  86.      }
  87.       supply_register (regno, buf);
  88.     }
  89.     /* now load up registers 36 - 38; special pc registers */
  90.     *(int *) &buf[0] = ptrace (3,inferior_pid,(char *)&u.pt_sigframe.dg_sigframe.sc_sxip - (char *)&u ,0);
  91.     supply_register (SXIP_REGNUM, buf);
  92.     *(int *) &buf[0] = ptrace (3, inferior_pid, (char *)&u.pt_sigframe.dg_sigframe.sc_snip - (char *)&u ,0);
  93.     supply_register (SNIP_REGNUM, buf);
  94.     *(int *) &buf[0] = ptrace (3, inferior_pid, (char *)&u.pt_sigframe.dg_sigframe.sc_sfip - (char *)&u ,0);
  95.     supply_register (SFIP_REGNUM, buf);
  96. }
  97.  
  98. /* Store our register values back into the inferior.
  99.    If REGNO is -1, do this for all registers.
  100.    Otherwise, REGNO specifies which register (so we can save time).  */
  101.  
  102. store_inferior_registers (regno)
  103.      int regno;
  104. {
  105.   register unsigned int regaddr;
  106.   char buf[80];
  107.  
  108.   struct USER u;
  109.  
  110. #if defined(BCS)
  111. #if defined(DGUX)
  112.  
  113.   unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
  114.  
  115. #endif /* defined (DGUX) */
  116. #else
  117.  
  118.   unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
  119.  
  120. #endif /* defined(BCS) */
  121. /*  offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; */
  122.   regaddr = offset;
  123.  
  124.   if (regno >= 0)
  125.     {
  126. /*      regaddr = register_addr (regno, offset); */
  127.         if (regno < PC_REGNUM)
  128.            { 
  129.          regaddr = offset + regno * sizeof (int);
  130.              errno = 0;
  131.              ptrace (6, inferior_pid, regaddr, read_register (regno));
  132.              if (errno != 0)
  133.            {
  134.              sprintf (buf, "writing register number %d", regno);
  135.              perror_with_name (buf);
  136.            }
  137.            }
  138.     else if (regno == SXIP_REGNUM)
  139.              ptrace (6, inferior_pid, SXIP_OFFSET, read_register(regno));
  140.     else if (regno == SNIP_REGNUM)
  141.          ptrace (6, inferior_pid, SNIP_OFFSET, read_register(regno));
  142.     else if (regno == SFIP_REGNUM)
  143.          ptrace (6, inferior_pid, SFIP_OFFSET, read_register(regno));
  144.     else printf ("Bad register number for store_inferior routine\n");
  145.     }
  146.   else { 
  147.          for (regno = 0; regno < NUM_REGS - 3; regno++)
  148.            {
  149.       /*      regaddr = register_addr (regno, offset); */
  150.               errno = 0;
  151.               regaddr = offset + regno * sizeof (int);
  152.               ptrace (6, inferior_pid, regaddr, read_register (regno));
  153.               if (errno != 0)
  154.              {
  155.               sprintf (buf, "writing register number %d", regno);
  156.               perror_with_name (buf);
  157.             }
  158.            }
  159.      ptrace (6,inferior_pid,SXIP_OFFSET,read_register(SXIP_REGNUM));
  160.      ptrace (6,inferior_pid,SNIP_OFFSET,read_register(SNIP_REGNUM));
  161.      ptrace (6,inferior_pid,SFIP_OFFSET,read_register(SFIP_REGNUM));
  162.        }    
  163.            
  164.  
  165. }
  166.  
  167. #if 0
  168. /* Core files are now a function of BFD.  */
  169.  
  170. void
  171. core_file_command (filename, from_tty)
  172.      char *filename;
  173.      int from_tty;
  174. {
  175.   int val;
  176.   extern char registers[];
  177.  
  178.   /* Need symbol file and one with tdesc info for corefiles to work */
  179.   if (!have_symbol_file_p())
  180.     error ("Requires symbol-file and exec-file");
  181.   if (!execfile)
  182.     error ("Requires exec-file and symbol-file");
  183.  
  184.   /* Discard all vestiges of any previous core file
  185.      and mark data and stack spaces as empty.  */
  186.  
  187.   if (corefile)
  188.     free (corefile);
  189.   corefile = 0;
  190.  
  191.   if (corechan >= 0)
  192.     close (corechan);
  193.   corechan = -1;
  194.  
  195.   data_start = 0;
  196.   data_end = 0;
  197.   stack_start = STACK_END_ADDR;
  198.   stack_end = STACK_END_ADDR;
  199.  
  200.   /* Now, if a new core file was specified, open it and digest it.  */
  201.  
  202.   if (filename)
  203.     {
  204.       filename = tilde_expand (filename);
  205.       make_cleanup (free, filename);
  206.       
  207.       if (have_inferior_p ())
  208.     error ("To look at a core file, you must kill the inferior with \"kill\".");
  209.       corechan = open (filename, O_RDONLY, 0);
  210.       if (corechan < 0)
  211.     perror_with_name (filename);
  212.       /* 4.2-style (and perhaps also sysV-style) core dump file.  */
  213.       {
  214.     struct USER u;
  215.  
  216.     int reg_offset;
  217.  
  218.     val = myread (corechan, &u, sizeof u);
  219.     if (val < 0)
  220.       perror_with_name (filename);
  221.     data_start = u.pt_o_data_start;
  222.  
  223.     data_end = data_start +  u.pt_dsize;
  224.     stack_start = stack_end -  u.pt_ssize;
  225.     data_offset = u.pt_dataptr;
  226.     stack_offset = data_offset + u.pt_dsize;
  227.  
  228. #if defined(BCS)
  229. #if defined(DGUX)
  230.  
  231.       reg_offset = 2048;
  232.  
  233.  
  234. #endif /* defined (DGUX) */
  235. #else
  236.  
  237.     /* original code: */
  238.     reg_offset = (int) u.pt_r0 - KERNEL_U_ADDR;
  239.  
  240. #endif /* defined(BCS) */
  241.  
  242.     /* I don't know where to find this info.
  243.        So, for now, mark it as not available.  */
  244. /*    N_SET_MAGIC (core_aouthdr, 0);  */
  245.     bzero ((char *) &core_aouthdr, sizeof core_aouthdr);
  246.  
  247.     /* Read the register values out of the core file and store
  248.        them where `read_register' will find them.  */
  249.  
  250.     {
  251.       register int regno;
  252.  
  253.       for (regno = 0; regno < NUM_REGS; regno++)
  254.         {
  255.           char buf[MAX_REGISTER_RAW_SIZE];
  256.  
  257.           val = lseek (corechan, register_addr (regno, reg_offset), 0);
  258.           if (val < 0)
  259.         perror_with_name (filename);
  260.  
  261.            val = myread (corechan, buf, sizeof buf);
  262.           if (val < 0)
  263.         perror_with_name (filename);
  264.           supply_register (regno, buf);
  265.         }
  266.     }
  267.       }
  268.       if (filename[0] == '/')
  269.     corefile = savestring (filename, strlen (filename));
  270.       else
  271.     {
  272.       corefile = concat (current_directory, "/", filename);
  273.     }
  274.       init_tdesc();
  275.       current_context = init_dcontext();
  276.       set_current_frame ( create_new_frame(get_frame_base (read_pc()), 
  277.                         read_pc ()));
  278.       select_frame (get_current_frame (), 0);
  279.       validate_files ();
  280.     }
  281.   else if (from_tty)
  282.     printf ("No core file now.\n");
  283. }
  284. #endif
  285.  
  286. /* blockend is the address of the end of the user structure */
  287. m88k_register_u_addr (blockend, regnum)
  288. {
  289.   struct USER u;
  290.   int ustart = blockend - sizeof (struct USER);
  291.   switch (regnum)
  292.     {
  293.     case 0:
  294.     case 1:
  295.     case 2:
  296.     case 3:
  297.     case 4:
  298.     case 5:
  299.     case 6:
  300.     case 7:
  301.     case 8:
  302.     case 9:
  303.     case 10:
  304.     case 11:
  305.     case 12:
  306.     case 13:
  307.     case 14:
  308.     case 15:
  309.     case 16:
  310.     case 17:
  311.     case 18:
  312.     case 19:
  313.     case 20:
  314.     case 21:
  315.     case 22:
  316.     case 23:
  317.     case 24:
  318.     case 25:
  319.     case 26:
  320.     case 27:
  321.     case 28:
  322.     case 29:
  323.     case 30:
  324.     case 31:          return (ustart + ((int) &u.pt_r0 - (int) &u) + sizeof(REGISTER_TYPE) * regnum);
  325.     case PSR_REGNUM:  return (ustart + ((int) &u.pt_psr - (int) &u));
  326.     case FPSR_REGNUM: return (ustart + ((int) &u.pt_fpsr - (int) &u));
  327.     case FPCR_REGNUM: return (ustart + ((int) &u.pt_fpcr - (int) &u));
  328.     case SXIP_REGNUM: return (ustart + SXIP_OFFSET); 
  329.     case SNIP_REGNUM: return (ustart + SNIP_OFFSET);
  330.     case SFIP_REGNUM: return (ustart + SFIP_OFFSET); 
  331.     default: return (blockend + sizeof (REGISTER_TYPE) * regnum);
  332.     }
  333. }
  334.